package com.example.base.system.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.base.excetion.GlobalExcetion;
import com.example.base.security.SecurityUtil;
import com.example.base.security.SysUser;
import com.example.base.security.domain.SysUserEntity;
import com.example.base.system.domain.SysLog;
import com.example.base.system.mapper.SysLogMapper;
import com.example.base.system.service.SysLogService;
import com.example.base.utils.IPUtils;
import io.swagger.annotations.ApiOperation;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author X.I.O
 * @since 2024-02-24
 */
@Service
@Transactional
@CacheConfig(cacheNames = "SysLogServiceImpl")
public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> implements SysLogService {

    @Cacheable(cacheNames = "syslog",key = "#id")
    @Override
    public SysLog getById(Serializable id){
        return super.getById(id);
    }

    @CacheEvict(cacheNames = "syslog", key = "#id")
    @Override
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

    @CacheEvict(cacheNames = "syslog", key = "#syslog.id")
    @Override
    public boolean updateById(SysLog syslog) {
        return super.updateById(syslog);
    }

    @CachePut(cacheNames = "syslog", key = "#syslog.id")
    public SysLog saveSysLog(SysLog syslog) throws GlobalExcetion {
        super.save(syslog);
        return syslog;
    }

    @CacheEvict(cacheNames = "syslog", key = "#syslog.id")
    public SysLog updateSysLogById(SysLog syslog) throws GlobalExcetion{
        super.updateById(syslog);
        return syslog;
    }


    public IPage<SysLog> page(Integer page, Integer pageSize) throws GlobalExcetion{
        LambdaQueryWrapper<SysLog> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(SysLog::getLogCreatedate);
        IPage<SysLog> iPage=super.baseMapper.selectPage(new Page(page,pageSize),lambdaQueryWrapper);
        return iPage;
    }

    @Override
    public void operateSysLog(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod,Exception ex) {
        // 获取处理器的类名
        String className = handlerMethod.getBeanType().getName();
        // 获取处理器的方法名
        String methodName = handlerMethod.getMethod().getName();
        SysUser userEntity=SecurityUtil.getSysUserEntity();

        SysLog sysLog=new SysLog();
        sysLog.setLogClass(className);
        sysLog.setLogClassMethod(methodName);
        sysLog.setLogCreatedate(new Date());
        sysLog.setLogMethod(request.getMethod());
        if(userEntity!=null){
            sysLog.setLogUid(userEntity.getUserId().toString());
            sysLog.setLogUsername(userEntity.getUserName());
        }
        String ip=IPUtils.getIpAddr(request);
        sysLog.setLogIp(ip);
        ApiOperation operation=handlerMethod.getMethodAnnotation(ApiOperation.class);
        if(operation!=null){
            sysLog.setLogName(operation.value());
        }else {
            sysLog.setLogName("未命名接口");
        }
        if(ex!=null){
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            ex.printStackTrace(pw);
            String exceptionMessage = sw.toString();
            //设置日志信息
            sysLog.setLogExection(exceptionMessage);
            sysLog.setLogStatus("fail");
        }else {
            sysLog.setLogStatus("success");
        }
        sysLog.setLogUrl(request.getRequestURI());
        sysLog.setLogParams(JSONObject.toJSONString(request.getParameterMap()));
        super.save(sysLog);
    }

    @Override
    public List<Map<String, Integer>> getPastDaysTotal(String startDate, String endDate) {
        return this.baseMapper.getPastDaysTotal(startDate,endDate);
    }

    @Override
    public List<Map<String, Object>> getPast15DaysTotal() {
        return this.baseMapper.getPast15DaysTotal();
    }


}
